# coding: utf-8
import datetime

import httpx
import peewee
from apscheduler.schedulers.blocking import BlockingScheduler


BASE_URL = "http://221.231.104.6:18806"

DATABASE = peewee.MySQLDatabase(
    "donjer", user="root", passwd="EUTI7395ejjttsap14", host="192.168.120.107", port=3306
)


class Data(peewee.Model):
    ID = peewee.IntegerField(primary_key=True)
    SENID = peewee.CharField()
    TIME = peewee.DateTimeField()
    IFCH = peewee.CharField()
    FACTV = peewee.CharField()
    CYCLE = peewee.CharField()
    STATE = peewee.CharField()
    TS = peewee.CharField()

    class Meta:
        database = DATABASE
        table_name = "ORACLE"


def load_site() -> dict:
    devices = httpx.get(BASE_URL + "/dbDevice/getList").json()["data"]
    site = {}
    location_types = set()
    device_types = set()
    for device in devices:
        if device["siteName"] not in site:
            site[device["siteName"]] = {}
            site[device["siteName"]]["siteCode"] = device["siteCode"]
            site[device["siteName"]]["devices"] = [device]
        elif site[device["siteName"]]["siteCode"] != device["siteCode"]:
            print(f" - [ERROR] {site[device['siteName']]['siteCode']} != {device['siteCode']}")
        site[device["siteName"]]["devices"].append(device)
        location_types.add(device["deviceAddress"])
        device_types.add(device["deviceName"])
    print(f"- Device location types: {location_types}")
    print(f"- Device types: {device_types}")
    return site


def post_data():
    sites = load_site()
    with DATABASE.connection_context():
        data = []
        for site_name, info in sites.items():
            site_code = info["siteCode"]
            totalRainData = None
            waterData = None
            upLevel = None
            lowLevel = None
            flowInfo = None
            time_str = "2020-01-01 00:00:00"
            for device in info["devices"]:
                query = (
                    Data.select()
                    .where(Data.SENID == device["deviceCode"])
                    .order_by(Data.TIME.desc())
                    .first()
                )
                if query is None:
                    print(
                        f"- [ERROR] Site {site_name}({site_code}) device {device['deviceName']}({device['deviceCode']}) not found in database."
                    )
                    continue
                if device["deviceName"] in ["水位计"]:
                    if device["deviceAddress"] in ["室外", "闸外", "下游", "外河"]:
                        upLevel = query.FACTV
                    elif device["deviceAddress"] in ["室内", "闸内", "上游", "内河"]:
                        lowLevel = query.FACTV
                    else:
                        waterData = query.FACTV
                elif device["deviceName"] in ["雨量计"]:
                    totalRainData = query.FACTV
                elif device["deviceName"] in ["流量计", "流量"]:
                    flowInfo = query.FACTV
                else:
                    print(
                        f"- [ERROR] Site {site_name}({site_code}) device {device['deviceName']}({device['deviceCode']}) type not recognized."
                    )
                    continue
                if query.TIME > datetime.datetime.strptime(time_str, "%Y-%m-%d %H:%M:%S"):
                    time_str = query.TIME.strftime("%Y-%m-%d %H:%M:%S")
            if time_str is None:
                continue
            data.append(
                {
                    "reportTime": time_str,
                    "readTime": time_str,
                    "rainData": None,
                    "waterData": waterData,
                    "upLevel": upLevel,  # upLevel: 室外、闸外、下游、外河
                    "lowLevel": lowLevel,  # lowLevel: 室内、闸内、上游、内河
                    "totalRainData": totalRainData,
                    "flowInfo": flowInfo,
                    "voltage": "12.0",
                    "siteCode": site_code,
                }
            )
            print(
                f"- [{data[-1]['readTime']}] {site_name}({data[-1]['siteCode']}) | rainData: {data[-1]['rainData']} | waterData: {data[-1]['waterData']} | upLevel: {data[-1]['upLevel']} | lowLevel: {data[-1]['lowLevel']} | flowInfo: {data[-1]['flowInfo']}"
            )
    now_str = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    print(f"[{now_str}] Found {len(data)} records.")
    try:
        response = httpx.post(BASE_URL + "/dbDeviceHistory/add", json=data, timeout=5)
        httpx.post("http://61.155.51.66:8006/dbDeviceHistory/add", json=data, timeout=5)
    except Exception as e:
        response = str(e)
    print(f"[{now_str}] {response}")


if __name__ == "__main__":
    post_data()
    scheduler = BlockingScheduler()
    scheduler.add_job(post_data, "interval", minutes=5)
    scheduler.start()
